#include "VersionControl.h"
#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QCryptographicHash>
#include <QUuid>
#include <QDebug>

namespace CollaborativeDesign {

VersionControl::VersionControl()
    : QObject(nullptr),
      m_currentVersionId(""),
      m_repositoryPath("")
{
}

VersionControl::~VersionControl()
{
    // 保存版本数据到磁盘
    saveVersionConfig();
}

Version VersionControl::createVersion(const QString& filePath, const QString& description)
{
    // 创建新版本
    Version version;
    version.id = generateVersionId();
    version.author = "当前用户"; // 应该从系统获取当前用户
    version.timestamp = QDateTime::currentDateTime();
    version.description = description;
    version.filePath = filePath;
    
    // 如果有当前版本，设置为父版本
    if (!m_currentVersionId.isEmpty()) {
        version.parentId = m_currentVersionId;
    }
    
    // 读取文件数据
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开文件:" << filePath;
        return version;
    }
    
    QByteArray data = file.readAll();
    file.close();
    
    // 保存版本数据
    if (saveVersionData(version, data)) {
        // 更新当前版本ID
        m_currentVersionId = version.id;
        
        // 添加到版本列表
        m_versions.append(version);
        
        // 发送版本创建信号
        emit versionCreated(version);
        
        qDebug() << "创建版本成功:" << version.id;
    } else {
        qWarning() << "创建版本失败";
    }
    
    return version;
}

QList<Version> VersionControl::getVersionHistory(const QString& filePath)
{
    QList<Version> history;
    
    // 筛选指定文件的版本历史
    for (const Version& version : m_versions) {
        if (version.filePath == filePath) {
            history.append(version);
        }
    }
    
    // 按时间排序
    std::sort(history.begin(), history.end(), [](const Version& a, const Version& b) {
        return a.timestamp > b.timestamp;
    });
    
    return history;
}

bool VersionControl::switchToVersion(const QString& versionId)
{
    // 查找版本
    Version targetVersion;
    bool found = false;
    
    for (const Version& version : m_versions) {
        if (version.id == versionId) {
            targetVersion = version;
            found = true;
            break;
        }
    }
    
    if (!found) {
        qWarning() << "版本不存在:" << versionId;
        return false;
    }
    
    // 加载版本数据
    QByteArray data = loadVersionData(versionId);
    if (data.isEmpty()) {
        qWarning() << "无法加载版本数据:" << versionId;
        return false;
    }
    
    // 写入文件
    QFile file(targetVersion.filePath);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning() << "无法打开文件进行写入:" << targetVersion.filePath;
        return false;
    }
    
    file.write(data);
    file.close();
    
    // 更新当前版本ID
    m_currentVersionId = versionId;
    
    // 发送版本切换信号
    emit versionSwitched(targetVersion);
    
    qDebug() << "切换到版本:" << versionId;
    return true;
}

bool VersionControl::mergeVersions(const QString& sourceVersionId, const QString& targetVersionId)
{
    // 检测冲突
    QStringList conflicts = detectConflicts(sourceVersionId, targetVersionId);
    
    if (!conflicts.isEmpty()) {
        qWarning() << "合并冲突:" << conflicts;
        // 这里应该实现冲突解决机制
        return false;
    }
    
    // 加载源版本和目标版本数据
    QByteArray sourceData = loadVersionData(sourceVersionId);
    QByteArray targetData = loadVersionData(targetVersionId);
    
    if (sourceData.isEmpty() || targetData.isEmpty()) {
        qWarning() << "无法加载版本数据";
        return false;
    }
    
    // 简单合并策略（实际应用中应该使用更复杂的合并算法）
    // 这里只是示例，实际应用中应该根据文件类型实现不同的合并策略
    QByteArray mergedData = targetData;
    
    // 创建新版本
    Version sourceVersion, targetVersion;
    for (const Version& version : m_versions) {
        if (version.id == sourceVersionId) {
            sourceVersion = version;
        }
        if (version.id == targetVersionId) {
            targetVersion = version;
        }
    }
    
    Version mergedVersion;
    mergedVersion.id = generateVersionId();
    mergedVersion.author = "当前用户"; // 应该从系统获取当前用户
    mergedVersion.timestamp = QDateTime::currentDateTime();
    mergedVersion.description = QString("合并版本 %1 到 %2").arg(sourceVersionId).arg(targetVersionId);
    mergedVersion.parentId = targetVersionId;
    mergedVersion.filePath = targetVersion.filePath;
    
    // 保存合并后的版本数据
    if (saveVersionData(mergedVersion, mergedData)) {
        // 更新当前版本ID
        m_currentVersionId = mergedVersion.id;
        
        // 添加到版本列表
        m_versions.append(mergedVersion);
        
        // 发送版本创建信号
        emit versionCreated(mergedVersion);
        
        qDebug() << "合并版本成功:" << mergedVersion.id;
        return true;
    } else {
        qWarning() << "合并版本失败";
        return false;
    }
}

QString VersionControl::compareVersions(const QString& versionId1, const QString& versionId2)
{
    // 加载两个版本的数据
    QByteArray data1 = loadVersionData(versionId1);
    QByteArray data2 = loadVersionData(versionId2);
    
    if (data1.isEmpty() || data2.isEmpty()) {
        qWarning() << "无法加载版本数据";
        return QString();
    }
    
    // 简单比较（实际应用中应该使用更复杂的差异比较算法）
    // 这里只是示例，实际应用中应该根据文件类型实现不同的比较策略
    QString text1 = QString::fromUtf8(data1);
    QString text2 = QString::fromUtf8(data2);
    
    QStringList lines1 = text1.split('\n');
    QStringList lines2 = text2.split('\n');
    
    QString result;
    int maxLines = qMax(lines1.size(), lines2.size());
    
    for (int i = 0; i < maxLines; ++i) {
        QString line1 = (i < lines1.size()) ? lines1[i] : "";
        QString line2 = (i < lines2.size()) ? lines2[i] : "";
        
        if (line1 != line2) {
            result += QString("行 %1:\n- %2\n+ %3\n").arg(i + 1).arg(line1).arg(line2);
        }
    }
    
    return result;
}

QString VersionControl::generateVersionId()
{
    // 使用UUID生成唯一ID
    return QUuid::createUuid().toString(QUuid::WithoutBraces);
}

bool VersionControl::saveVersionData(const Version& version, const QByteArray& data)
{
    // 确保版本库目录存在
    QDir dir(m_repositoryPath);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            qWarning() << "无法创建版本库目录:" << m_repositoryPath;
            return false;
        }
    }
    
    // 保存版本数据
    QString dataFilePath = QString("%1/%2.data").arg(m_repositoryPath).arg(version.id);
    QFile dataFile(dataFilePath);
    if (!dataFile.open(QIODevice::WriteOnly)) {
        qWarning() << "无法创建版本数据文件:" << dataFilePath;
        return false;
    }
    
    dataFile.write(data);
    dataFile.close();
    
    // 保存版本配置
    saveVersionConfig();
    
    return true;
}

QByteArray VersionControl::loadVersionData(const QString& versionId)
{
    QString dataFilePath = QString("%1/%2.data").arg(m_repositoryPath).arg(versionId);
    QFile dataFile(dataFilePath);
    if (!dataFile.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开版本数据文件:" << dataFilePath;
        return QByteArray();
    }
    
    QByteArray data = dataFile.readAll();
    dataFile.close();
    
    return data;
}

QStringList VersionControl::detectConflicts(const QString& sourceVersionId, const QString& targetVersionId)
{
    QStringList conflicts;
    
    // 加载源版本和目标版本数据
    QByteArray sourceData = loadVersionData(sourceVersionId);
    QByteArray targetData = loadVersionData(targetVersionId);
    
    if (sourceData.isEmpty() || targetData.isEmpty()) {
        conflicts << "无法加载版本数据";
        return conflicts;
    }
    
    // 简单冲突检测（实际应用中应该使用更复杂的冲突检测算法）
    // 这里只是示例，实际应用中应该根据文件类型实现不同的冲突检测策略
    QString sourceText = QString::fromUtf8(sourceData);
    QString targetText = QString::fromUtf8(targetData);
    
    QStringList sourceLines = sourceText.split('\n');
    QStringList targetLines = targetText.split('\n');
    
    int maxLines = qMin(sourceLines.size(), targetLines.size());
    
    for (int i = 0; i < maxLines; ++i) {
        if (sourceLines[i] != targetLines[i]) {
            conflicts << QString("行 %1 冲突").arg(i + 1);
        }
    }
    
    return conflicts;
}

bool VersionControl::saveVersionConfig()
{
    // 确保版本库目录存在
    QDir dir(m_repositoryPath);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            qWarning() << "无法创建版本库目录:" << m_repositoryPath;
            return false;
        }
    }
    
    // 创建JSON文档
    QJsonArray versionsArray;
    
    for (const Version& version : m_versions) {
        QJsonObject versionObj;
        versionObj["id"] = version.id;
        versionObj["author"] = version.author;
        versionObj["timestamp"] = version.timestamp.toString(Qt::ISODate);
        versionObj["description"] = version.description;
        versionObj["parentId"] = version.parentId;
        versionObj["filePath"] = version.filePath;
        
        versionsArray.append(versionObj);
    }
    
    QJsonObject rootObj;
    rootObj["versions"] = versionsArray;
    rootObj["currentVersionId"] = m_currentVersionId;
    
    QJsonDocument doc(rootObj);
    
    // 保存配置文件
    QString configFilePath = QString("%1/versions.json").arg(m_repositoryPath);
    QFile configFile(configFilePath);
    if (!configFile.open(QIODevice::WriteOnly)) {
        qWarning() << "无法创建版本配置文件:" << configFilePath;
        return false;
    }
    
    configFile.write(doc.toJson());
    configFile.close();
    
    return true;
}

bool VersionControl::loadVersionConfig()
{
    QString configFilePath = QString("%1/versions.json").arg(m_repositoryPath);
    QFile configFile(configFilePath);
    if (!configFile.exists()) {
        // 配置文件不存在，初始化空版本列表
        m_versions.clear();
        m_currentVersionId = "";
        return true;
    }
    
    if (!configFile.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开版本配置文件:" << configFilePath;
        return false;
    }
    
    QByteArray data = configFile.readAll();
    configFile.close();
    
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull() || !doc.isObject()) {
        qWarning() << "版本配置文件格式错误";
        return false;
    }
    
    QJsonObject rootObj = doc.object();
    
    // 读取当前版本ID
    m_currentVersionId = rootObj["currentVersionId"].toString();
    
    // 读取版本列表
    m_versions.clear();
    QJsonArray versionsArray = rootObj["versions"].toArray();
    
    for (const QJsonValue& value : versionsArray) {
        QJsonObject versionObj = value.toObject();
        
        Version version;
        version.id = versionObj["id"].toString();
        version.author = versionObj["author"].toString();
        version.timestamp = QDateTime::fromString(versionObj["timestamp"].toString(), Qt::ISODate);
        version.description = versionObj["description"].toString();
        version.parentId = versionObj["parentId"].toString();
        version.filePath = versionObj["filePath"].toString();
        
        m_versions.append(version);
    }
    
    return true;
}

} // namespace CollaborativeDesign 